package servidores;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.io.IOException;

public class ThreadClienteDNS extends Thread {
   
    private Socket socketClienteDNS;
    private ObjectInputStream flujoEntrada;
    private ObjectOutputStream flujoSalida;
    private List<ThreadClienteDNS> listaClientesDNS;
          
    public ThreadClienteDNS(Socket socketClientDNS, List<ThreadClienteDNS> listaClientsDNS) throws IOException {
        this.socketClienteDNS = socketClientDNS;
	    this.flujoSalida = new ObjectOutputStream(socketClientDNS.getOutputStream());    
    	this.flujoEntrada = new ObjectInputStream(socketClientDNS.getInputStream()); 
        this.listaClientesDNS = listaClientsDNS;
    }
   
    public void run () {
        try {
        	while (true) {
                String mensaje = flujoEntrada.readUTF();
                System.out.println("BackEnd-DNS: Ejecutando " + mensaje + "[threadId: " + this.getId() + "]");
                if ("getClientsTime".equalsIgnoreCase(mensaje)) {
                	try {
                	    sendToClientFront(getClientsTime(),flujoSalida);
					} catch (ClassNotFoundException e) {
                	    sendToClientFront("Error getClientsTime()",flujoSalida);
						e.printStackTrace();
					}
                }
                if ("askCord".equalsIgnoreCase(mensaje)) {
                	try {
                	    sendToClientFront(askCordinador(),flujoSalida);
					} catch (ClassNotFoundException e) {
                	    sendToClientFront("Error getClientsTime()",flujoSalida);
						e.printStackTrace();
					}
                }
            }
        }
        catch (IOException ex) {
        	System.out.println("BackEnd-DNS: Un Cliente se ha desconectado [threadId: " + this.getId() + "]");
        	//ex.printStackTrace();
        }
        finally {
        	listaClientesDNS.remove(this);
            cerrarFlujos();
        }
    }
    
    private void sendToClientFront(Object mensaje, ObjectOutputStream flujoSalida) {
        try {
            flujoSalida.writeObject(mensaje);
            flujoSalida.flush();
        }    
        catch (IOException ex) {
        	System.out.println("BackEnd-DNS: Error en sendToClient [threadId: " + this.getId() + "]");
            ex.printStackTrace();                 
        } 
    } 

    private void cerrarFlujos() { 
        try {
             flujoEntrada.close();
             flujoSalida.close();
             socketClienteDNS.close();
        }
        catch (IOException ex) {
        	System.out.println("BackEnd-DNS: Error en cerrarFlujos [threadId: " + this.getId() + "]");
        	ex.printStackTrace();
        }        
    }
    
    public Object getClientsTime() throws ClassNotFoundException {
		List <String>  listaRelojes = new ArrayList<String>();
			
		for (ThreadClienteDNS threadClientFront : this.listaClientesDNS) {
			try {
				sendToClientFront("getTime",threadClientFront.flujoSalida);
				String timeClient = (String) threadClientFront.flujoEntrada.readObject();
				listaRelojes.add(timeClient);
			} catch (IOException e) {
		    	System.out.println("BackEnd-DNS: Error en getClientsTime() [threadId: " + this.getId() + "]");
		        e.printStackTrace();
			} 
		}
		
		return (Object) listaRelojes;
	}
    
    public Object askCordinador() throws ClassNotFoundException {
		if (this.listaClientesDNS.size() == 1) {
			return (Object) "YC";
		}
		else
			return (Object) "NC";
	}
}
